Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(cdrmodal): fixes the issue where screen readers can read content … #151

Closed
wants to merge 2 commits into from

Conversation

daemoncron
Copy link
Collaborator

@daemoncron daemoncron commented Oct 27, 2023

No description provided.

…outside the modal

Upon mounting, any modal instances will now be teleported to the root of the document.body element.
When the modal is opened, other top-level children of the body element will be marked aria-hidden to
prevent them from being read by certain screen readers.

BREAKING CHANGE: This may not be a breaking change for teams, but they will need to test that it
works for their application. Because this will move the modal from the spot they're originally
mounting it to the body element, there could be unexpected effects if they were relying on it to
remain in that spot.
@daemoncron daemoncron requested a review from benjag October 27, 2023 19:07
@daemoncron daemoncron self-assigned this Oct 27, 2023
Comment on lines +31 to +39
<!-- start: testing modal content show/hide -->
<div
aria-hidden="true"
style="opacity: 0;"
>something already aria-hidden</div>
<div hidden>something display: none;</div>
<div style="opacity: 0;">another div of outside content, not aria-hidden</div>
<!-- end: testing modal content show/hide -->
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO this will be removed, for display/testing only

@@ -92,11 +102,11 @@ let lastActive: Element | null;
const modalClosed = ref(!props.opened);
const isOpening = ref(false);

interface offsetValues {
interface OffsetValues {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sonarlint caught this formatting.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd ask to remove these changes, we use a different config

@@ -190,6 +201,62 @@ const removeNoScroll = () => {
}
};

Copy link
Collaborator Author

@daemoncron daemoncron Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Modal scripts begin below

':not(style)',
':not([data-is-modal])',
':not([aria-hidden=true])',
]
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Summary of these selectors: find all direct children of the body element, that are not:

  • script or style tags
  • that are not this modal or other modals (they should be hidden when the top modal is open anyway)
  • that are not already aria-hidden


// for the remaining, check if they should be hidden
contentBodyChildren.forEach((el) => {
if (getComputedStyle(el).getPropertyValue('display') !== 'none') {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, skip any that have a computed value of display: none.

contentBodyChildren.forEach((el) => {
if (getComputedStyle(el).getPropertyValue('display') !== 'none') {
// TODO - temp to be sure we tagged right
el.setAttribute('data-modal-hide', '');
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't strictly necessary, but would be pretty helpful in debugging. I'm 50/50 on whether to leave it or remove it.

const hideModalBackgroundContent = () => {
// only run the expensive DOM scraping once
if (!backgroundNodesDiscovered) {
findBackgroundContentNodes();
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put this here instead of in a beforeMount hook, for example.
Two reasons:

  1. Performance: this may never need to run at all.
  2. Our pages continue loading content at the body level way past when the DOMContentLoaded event fires. Playing around with this in the PDP, I had to use a setTimeout of something like 5 seconds (on a fast connection) to get all of our little body children loaded.

Comment on lines +353 to +357
const textContentStyle = computed(() => ({
maxHeight: `${scrollMaxHeight.value}px`,
paddingRight: `${scrollPadding.value}px`,
}));

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Moved this out of template - was throwing a lint error for line length having it inline below.

:class="mapClasses(style, baseClass, !opened ? 'cdr-modal--closed' : '')"
ref="wrapperEl"
>
<Teleport to="body">
Copy link
Collaborator Author

@daemoncron daemoncron Oct 27, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template change 1

:class="[style['cdr-modal__outerWrap'], wrapperClass]"
:class="mapClasses(style, baseClass, !opened ? 'cdr-modal--closed' : '')"
ref="wrapperEl"
data-is-modal
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

template change 2

@@ -295,92 +372,91 @@ onUnmounted(() => {
window.removeEventListener('resize', handleResize);
});


</script>

<template>
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lots of formatting fixes in the modal, noted actual changes below.

Comment on lines +95 to +97
// TODO not sure why this was setup like this?
opened: false,
// opened: this.$route.name === 'Modals',
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Side fix: I found this really difficult to develop with - I needed to see the page state before and after modal load. I wasn't sure if there was a reason we had it load on going to the route, but if not I'd love to leave it like this.

@daemoncron daemoncron removed the request for review from benjag November 3, 2023 17:04
@daemoncron daemoncron closed this Nov 3, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants